const { join, relative } = require("path");
const fs = require("fs");
const chalk = require("chalk");
const { program } = require("commander");
const child_process = require("child_process");

const indexContent = readFile("./index.ts");
const tsconfigContent = readFile("./tsconfig.json");
const packageContent = readFile("./package.json");
const packageJson = JSON.parse(JSON.stringify(packageContent));

program.version(packageJson.version);
program
  .option("-c --create", "a file name argument")
  .option("-d --delete", "delete exist package")
  .parse(process.argv);

const opts = program.opts();

function log(path) {
  const resolvePath = relative(process.cwd() + "/packages", path);

  console.log(`create ${chalk.yellow(resolvePath)}`);
}

function relativePath(path) {
  if (!path) return;

  return join(__dirname, path);
}

function readFile(path) {
  if (!path) return;

  return fs.readFileSync(relativePath(path), "utf8");
}

function writeFile(path, content) {
  if (!path) return;

  fs.writeFileSync(path, content, "utf8");
}

// create folder
async function createFolder() {
  const reg = /^[a-z]{1,}(\-[a-z])*/g;

  if (!reg.test(program.args[1])) {
    return console.log(
      chalk.yellow("命名必需以小写字母开头，词组要以连字符串联")
    );
  }

  const pluginRootPath = `../packages/${program.args[0]}`;
  const path = relativePath(pluginRootPath);

  await fs.mkdirSync(path);

  await log(path);

  return path;
}

// create package.json
async function createPackageJson(path, content) {
  const pluginName = `babel-plugin-${program.args[0]}`;

  writeFile(
    path + "/package.json",
    content.replace("template-package", pluginName)
  );

  log(path + "/package.json");
}

// create tsconfig.json
async function createTsconfig(path, content) {
  writeFile(path + "/tsconfig.json", content);

  log(path + "/tsconfig.json");
}

// create src/index.ts
async function createMain(path, content) {
  if (!fs.existsSync(path + "/src")) {
    fs.mkdirSync(path + "/src");

    log(path + "/src");
  }
  writeFile(path + "/src/index.ts", content);

  log(path + "/src/index.ts");
}

async function createPackage() {
  if (!opts.create) {
    return;
  }

  if (fs.existsSync(relativePath(`../packages/${program.args[0]}`))) {
    return chalk.yellow(`The ${program.args[0]} folder already exists`);
  }

  // create folder
  const folderPath = await createFolder();

  await createPackageJson(folderPath, packageContent);
  await createTsconfig(folderPath, tsconfigContent);
  await createMain(folderPath, indexContent);
}

async function deletePackage() {
  if (!opts.delete) {
    return;
  }

  const path = relativePath(`../packages/${program.args[0]}`);

  if (!fs.existsSync(path)) {
    return chalk.yellow(`The ${program.args[1]} folder does not exist`);
  }

  const workerProcess = child_process.exec(
    `rm -rf ${path}`,
    (error, stdout, stderr) => {
      if (error) {
        console.log(error.stack);
        console.log("Error code: " + error.code);
        console.log("Signal received: " + error.signal);
      }
    }
  );

  workerProcess.on("exit", function (code) {
    console.log(`Successfully deleted`);
  });
}

async function initCommand() {
  await createPackage();
  await deletePackage();
}

initCommand();
